package com.xdf.whiteaccount.service.impl;

import com.xdf.whiteaccount.dao.ContactCompanyMapper;
import com.xdf.whiteaccount.dao.DyeFabricPlanMapper;
import com.xdf.whiteaccount.entity.ContactCompany;
import com.xdf.whiteaccount.entity.DyeFabricPlan;
import com.xdf.whiteaccount.entity.GjrkbillCp;
import com.xdf.whiteaccount.service.BillCodeService;
import com.xdf.whiteaccount.service.GjrkbillCpService;
import com.xdf.whiteaccount.utils.BusinessException;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.xdf.whiteaccount.entity.CpBillfh;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import com.xdf.whiteaccount.dao.CpBillfhMapper;
import com.xdf.whiteaccount.service.CpBillfhService;

/**
 * @Description : com.xdf.whiteaccount.service.impl(业务层实现类,该类为生成器自动生成).
 * @Author : 张柯
 * @Date : 2021-06-25 09:44:52
 */
@Service
public class CpBillfhServiceImpl implements CpBillfhService {
    @Autowired
    private CpBillfhMapper dao;
    @Autowired
    private GjrkbillCpService gjrkbillCpService;
    @Autowired
    private DyeFabricPlanMapper dyeFabricPlanMapper;
    @Lazy
    @Autowired
    private CpBillfhServiceImpl meService;
    @Autowired
    private BillCodeService billCodeService;
    @Autowired
    private ContactCompanyMapper contactCompanyMapper;

    public static final String BILL_CODE_FLAG = "色布发货";

    /**
     * @Describe 新增方法
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(CpBillfh record) throws Exception {
        return dao.insert(record);
    }

    /**
     * @Describe 选择新增
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertSelective(CpBillfh record) throws Exception {
        return dao.insertSelective(record);
    }

    /**
     * @Describe 批量新增
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int multiInsert(List<CpBillfh> list) throws Exception {
        return dao.multiInsert(list);
    }

    /**
     * @Describe 修改
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByPrimaryKey(CpBillfh record) throws Exception {
        return dao.updateByPrimaryKey(record);
    }

    /**
     * @Describe 选择修改
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByPrimaryKeySelective(CpBillfh record) throws Exception {
        return dao.updateByPrimaryKeySelective(record);
    }

    /**
     * @Describe 修改
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(CpBillfh record) throws Exception {
        return dao.updateByPrimaryKey(record);
    }

    /**
     * @Describe 批量修改
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int multiUpdate(List<CpBillfh> list) throws Exception {
        list.forEach(item -> dao.updateByPrimaryKeySelective(item));
        return list.size();
    }

    /**
     * @Describe 根据主键查询
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    public CpBillfh selectByPrimaryKey(Integer id) throws Exception {
        return dao.selectByPrimaryKey(id);
    }

    /**
     * @Describe 根据主键删除
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteByPrimaryKey(Integer id) throws Exception {
        return dao.deleteByPrimaryKey(id);
    }

    /**
     * @Describe 根据Entity查询
     * @author 张柯
     * @Date 2021-06-25 09:44:52
     */
    @Override
    public List<CpBillfh> listQuery(CpBillfh record) throws Exception {
        return dao.selectByParam(record);
    }

    /**
     * 根据色布打卷入库主键数组统计后写入色布发货数据
     * @param jrkIdList
     * @return
     */
    @Override
    public List<CpBillfh> insert8JrkIdList(List<Integer> jrkIdList) throws Exception {
        List<CpBillfh> cpBillfhList = selectCollectionByKeyList(jrkIdList);
        if(cpBillfhList == null || cpBillfhList.size() == 0) return null;

        List<CpBillfh> ret = new ArrayList<>();
        for (CpBillfh item : cpBillfhList) {
            insertSelective(item);
            ret.add(item);
        }
        return ret;
    }

    @Transactional
    @Override
    public List<CpBillfh> insert8JrkIdList(CpBillfh record, List<Integer> jrkIdList) throws Exception{
        // 根据打卷主键获取打卷明细数据时候要求两个字段：B_FPDID,B_upload 都是0
        // 即同时满足条件：没有发货，没有被其他设备扫码（正在发货）
        List<CpBillfh> cpBillfhList = selectCollectionByKeyList(jrkIdList);
        if(cpBillfhList == null || cpBillfhList.size() == 0) return null;

        List<DyeFabricPlan> dyeFabricPlanList = dyeFabricPlanMapper.selectByJrkCPIdList(jrkIdList);
        String contactCompanyId = dyeFabricPlanList.get(0).getContactCompanyId();
        for (DyeFabricPlan dyeFabricPlan : dyeFabricPlanList) {
            if (!Optional.ofNullable(contactCompanyId).orElse("").equals(Optional.ofNullable(dyeFabricPlan.getContactCompanyId()).orElse("")))
                throw new RuntimeException("查询到的客户名不同！");
        }
        ContactCompany contactCompany = contactCompanyMapper.selectByPrimaryKey(contactCompanyId);

        List<CpBillfh> ret = new ArrayList<>();
        for (CpBillfh item : cpBillfhList) {
            //# region 新增一笔发货明细（表cp_billfh新增一行数据）
            String newBillCode = billCodeService.getNewBillCode(BILL_CODE_FLAG);
            item.setBillcode(newBillCode);

            String client = Optional.ofNullable(contactCompany.getCompanyName()).orElse("");
            if(client.length()>0) item.setClient(client);

            String checkout = Optional.ofNullable(record.getCheckout()).orElse("");
            if(checkout.length()>0) item.setCheckout(checkout);

            String memo = Optional.ofNullable(record.getMemo()).orElse("");
            if(memo.length()>0) item.setMemo(memo);

            String manager = Optional.ofNullable(record.getManager()).orElse("");
            if(manager.length()>0) item.setManager(manager);

            String carnumber = Optional.ofNullable(record.getCarnumber()).orElse("");
            if(carnumber.length()>0) item.setCarnumber(carnumber);

            String remark = Optional.ofNullable(record.getRemark()).orElse("");
            if(remark.length()>0) item.setRemark(remark);

            Integer printheader = Optional.ofNullable(record.getPrintheader()).orElse(1);
            item.setPrintheader(printheader);
            Integer hideClient = Optional.ofNullable(record.getHideClient()).orElse(0);
            item.setHideClient(hideClient);
            Integer showPrice = Optional.ofNullable(record.getShowPrice()).orElse(1);
            item.setShowPrice(showPrice);
            BigDecimal price = Optional.ofNullable(record.getPrice()).orElse(BigDecimal.valueOf(0));
            item.setPrice(price);

            // 保存发货单明细数据并获取自增的主键
            meService.insertSelective(item);
            //#endregion

            /*
            // 过滤符合当前发货：品名、规格、颜色的打卷计划数据（字段upload是打卷表主键）
            // 等待后面写入发货主键
            List<DyeFabricPlan> targetPlanList = dyeFabricPlanList.stream().filter(shelve ->
                    shelve.getProductName().equalsIgnoreCase(item.getProductName()) &&
                            (shelve.getGreyfabricWidth() + "*" + shelve.getMaterialSpecification()).equalsIgnoreCase(item.getSpecification()) &&
                            shelve.getColor().equalsIgnoreCase(item.getColor()) &&
                            Optional.ofNullable(shelve.getClientAlias()).orElse("").equalsIgnoreCase(item.getSignstr())
            ).collect(Collectors.toList());

            // 向打卷表字段 B_FPDID 写入发货主键
            if(targetPlanList.size() > 0){
                for (DyeFabricPlan plan : targetPlanList) {
                    GjrkbillCp gjrkbillCp = new GjrkbillCp();
                    gjrkbillCp.setbItemID(plan.getUpload());// plan.getUpload() = 成品打卷表主键 = g_jrkbill_cp.B_ItemID
                    gjrkbillCp.setbFPDID(item.getId());
                    gjrkbillCpService.updateByPrimaryKeySelective(gjrkbillCp);
                }
            }
            */
            // 2025年8月15日 08:28:06 chanchaw 注释上面代码，采用下面的逻辑
            // 为方法 CpBillfhMapper.xml # selectCollectionByKeyList
            // 新增字段 color_no 保存分组汇总关联的打卷主键
            // 遍历后设置发货明细主键
            String jrkIds = Optional.ofNullable(item.getColorNo()).orElse("");
            if(jrkIds.length() == 0) throw new BusinessException("生成预发货数据后关联打卷明细出现异常，请联系开发人员解决");
            String[] jrkIdArr = jrkIds.split(",");
            if(jrkIdArr.length == 0) throw new BusinessException("生成预发货数据后关联打卷明细出现异常，请联系开发人员解决");
            for (String id : jrkIdArr) {
                GjrkbillCp gjrkbillCp = new GjrkbillCp();
                gjrkbillCp.setbItemID(Integer.valueOf(id));
                gjrkbillCp.setbFPDID(item.getId());
                gjrkbillCpService.updateByPrimaryKeySelective(gjrkbillCp);
            }

            ret.add(item);
        }

        return ret;
    }

    @Transactional
    @Override
    public List<CpBillfh> insert8ShelvesList(List<String> shelvesList) throws Exception{
        List<CpBillfh> cpBillfhList = meService.selectCollectionByShelvesList(shelvesList);
        if(cpBillfhList == null || cpBillfhList.size() == 0) return null;

        // 根据货架号查询获取对应的：货架号、品名、规格、颜色
        // 后面创建发货与打卷的关联外键数据时用到
        List<DyeFabricPlan> dyeFabricPlanList = dyeFabricPlanMapper.selectByShelvesList(shelvesList);

        List<CpBillfh> ret = new ArrayList<>();
        for (CpBillfh item : cpBillfhList) {
            meService.insertSelective(item);

            // 将发货明细主键回写入打卷明细表，建立两者的关联
            List<DyeFabricPlan> targetShelveList = dyeFabricPlanList.stream().filter(shelve ->
                    shelve.getProductName().equalsIgnoreCase(item.getProductName()) &&
                            shelve.getMaterialSpecification().equalsIgnoreCase(item.getSpecification()) &&
                            shelve.getColor().equalsIgnoreCase(item.getColor())
            ).collect(Collectors.toList());
            // 有相同：品名、规格、颜色的货架号，遍历其设置发货主键，属性 planCode 中保存的是货架号
            if(targetShelveList.size() > 0)
                targetShelveList.forEach(shelve -> dao.buildJrkRelation(item.getId(),shelve.getPlanCode()));

            ret.add(item);
        }
        return ret;
    }

    /**
     * 根据色布打卷主键查询并汇总返回色布发货数据集合
     * @param jrkIdList
     * @return
     */
    @Override
    public List<CpBillfh> selectCollectionByKeyList(List<Integer> jrkIdList){
        if(jrkIdList == null || jrkIdList.size() == 0) return null;
        return dao.selectCollectionByKeyList(jrkIdList);
    }

    @Override
    public List<CpBillfh> selectCollectionByShelvesList(List<String> shelvesList){
        if(shelvesList == null || shelvesList.size() == 0) return null;
        return dao.selectCollectionByShelvesList(shelvesList);
    }

    @Override
    public List<CpBillfh> insert8ShelvesList(CpBillfh record, List<String> shelvesList) throws Exception{
        List<CpBillfh> cpBillfhList = meService.selectCollectionByShelvesList(shelvesList);
        if(cpBillfhList == null || cpBillfhList.size() == 0) return null;

        // 根据货架号查询获取对应的：货架号、品名、规格、颜色
        // 后面创建发货与打卷的关联外键数据时用到
        List<DyeFabricPlan> dyeFabricPlanList = dyeFabricPlanMapper.selectByShelvesList(shelvesList);

        for (CpBillfh item : cpBillfhList) {
            //BeanUtils.copyProperties(item,record);
            String newBillCode = billCodeService.getNewBillCode(BILL_CODE_FLAG);
            item.setBillcode(newBillCode);

            String client = Optional.ofNullable(record.getClient()).orElse("");
            if(client.length()>0) item.setClient(client);

            String checkout = Optional.ofNullable(record.getCheckout()).orElse("");
            if(checkout.length()>0) item.setCheckout(checkout);

            String memo = Optional.ofNullable(record.getMemo()).orElse("");
            if(memo.length()>0) item.setMemo(memo);

            String manager = Optional.ofNullable(record.getManager()).orElse("");
            if(manager.length()>0) item.setManager(manager);

            String carnumber = Optional.ofNullable(record.getCarnumber()).orElse("");
            if(carnumber.length()>0) item.setCarnumber(carnumber);

            String remark = Optional.ofNullable(record.getRemark()).orElse("");
            if(remark.length()>0) item.setRemark(remark);

            Integer printheader = Optional.ofNullable(record.getPrintheader()).orElse(1);
            item.setPrintheader(printheader);
            Integer hideClient = Optional.ofNullable(record.getHideClient()).orElse(0);
            item.setHideClient(hideClient);
            Integer showPrice = Optional.ofNullable(record.getShowPrice()).orElse(1);
            item.setShowPrice(showPrice);
            BigDecimal price = Optional.ofNullable(record.getPrice()).orElse(BigDecimal.valueOf(0));
            item.setPrice(price);
        }

        List<CpBillfh> ret = new ArrayList<>();
        for (CpBillfh item : cpBillfhList) {
            // 将发货明细主键回写入打卷明细表，建立两者的关联
            List<DyeFabricPlan> targetShelveList = dyeFabricPlanList.stream().filter(shelve ->
                shelve.getProductName().equalsIgnoreCase(item.getProductName()) &&
                        shelve.getMaterialSpecification().equalsIgnoreCase(item.getSpecification()) &&
                        shelve.getColor().equalsIgnoreCase(item.getColor())
            ).collect(Collectors.toList());

            Long id = targetShelveList.get(0).getId();
            item.setPlanid(id.intValue());
            meService.insertSelective(item);

            // 有相同：品名、规格、颜色的货架号，遍历其设置发货主键，属性 planCode 中保存的是货架号
            if(targetShelveList.size() > 0)
                targetShelveList.forEach(shelve -> dao.buildJrkRelation(item.getId(),shelve.getPlanCode()));

            ret.add(item);
        }
        return ret;
    }

    /**
     * 作废一个发货颜色汇总数据，要做如下关联清除：
     * 1. 作废发货单数据
     * 2. 清除成品打卷表字段 B_FPDID
     * 3. 清除成品打卷表字段 B_upload
     * 4. 清除成品打卷表字段 scan_id
     * @param id
     * @return
     */
    @Transactional
    @Override
    public int setVoid(Integer id){
        CpBillfh cpBillfh = dao.selectByPrimaryKey(id);
        if(cpBillfh == null) throw new BusinessException("没有找到该发货数据！");
        cpBillfh.setState(0);
        dao.updateByPrimaryKeySelective(cpBillfh);// 作废发货数据
        return gjrkbillCpService.clearFPDIDBatch(id);// 清除：发货主键、扫描设备编号、扫描流水号
    }

    /**
     * 从发货单中剔除一行细码单数据
     * @param id
     * @return
     */
    @Override
    public int updatefh(Integer id) {
        CpBillfh cpBillfh = dao.selectByPrimaryKey(id);
        if (cpBillfh == null) throw new RuntimeException("细码单已发货或已作废！！");
        cpBillfh.setMainId(null);
        cpBillfh.setState(1);
        return dao.updateByPrimaryKey(cpBillfh);
    }
}